package com.babel.util.lide;

import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import org.apache.commons.codec.binary.Base64;

/**
 * 利得接口RSA签名工具类
 * @author lyj
 * @date 2017年5月10日---下午5:37:45
 */
public class RSASignatureUtil {

    /** 
     * 签名算法 
     */
    public static final String SIGN_ALGORITHMS = "SHA1WithRSA";

    /** 
    * RSA签名 
    * @param content 待签名数据 
    * @param privateKey 商户私钥 
    * @param encode 字符集编码 
    * @return 签名值 
     * @throws Exception 
    */
    public static String sign(String content, String privateKey, String encode) throws Exception {
	try {
	    PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));

	    KeyFactory keyf = KeyFactory.getInstance("RSA");
	    PrivateKey priKey = keyf.generatePrivate(priPKCS8);

	    java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

	    signature.initSign(priKey);
	    signature.update(content.getBytes(encode));

	    byte[] signed = signature.sign();

	    return Base64.encodeBase64String(signed);
	} catch (Exception e) {
	    System.err.println("RSASignatureUtils.sign() e: " + e);
	    throw e;
	}
    }

    public static String sign(String content, String privateKey) throws Exception {
	try {
	    PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
	    KeyFactory keyf = KeyFactory.getInstance("RSA");
	    PrivateKey priKey = keyf.generatePrivate(priPKCS8);
	    java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);
	    signature.initSign(priKey);
	    signature.update(content.getBytes());
	    byte[] signed = signature.sign();
	    return Base64.encodeBase64String(signed);
	} catch (Exception e) {
	    System.err.println("RSASignatureUtils.sign() e: " + e);
	    throw e;
	}
    }

    /** 
    * RSA验签名检查 
    * @param content 待签名数据 
    * @param sign 签名值 
    * @param publicKey 分配给开发商公钥 
    * @param encode 字符集编码 
    * @return 布尔值 
    */
    public static boolean verify(String content, String sign, String publicKey, String encode) {
	try {
	    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	    byte[] encodedKey = Base64.decodeBase64(publicKey);
	    PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

	    java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

	    signature.initVerify(pubKey);
	    signature.update(content.getBytes(encode));

	    boolean bverify = signature.verify(Base64.decodeBase64(sign));
	    return bverify;

	} catch (Exception e) {
	    System.err.println("RSASignatureUtils.verify() e: " + e);
	    return false;
	}
    }

    public static boolean verify(String content, String sign, String publicKey) {
	try {
	    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
	    byte[] encodedKey = Base64.decodeBase64(publicKey);
	    PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));

	    java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS);

	    signature.initVerify(pubKey);
	    signature.update(content.getBytes());

	    boolean bverify = signature.verify(Base64.decodeBase64(sign));
	    return bverify;

	} catch (Exception e) {
	    System.err.println("RSASignatureUtils.verify() e: " + e);
	    return false;
	}
    }

    public static void main(String[] args) throws Exception {

	String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTw7AlUJ4LoCYRIH3v+rjBpQ0VKtb16Bps/SjfQWCxm966z1d1DGs1cqGLDvzj6M0avYdDzXnVHlNku4p8VEsdsQpczCt5kW2fmWguOtAD/6MCuUoQoNwPpPimww+7bGK0vdWKPKoLgOffpG0eNnSdYWDoWwGcVoU6SLMtrt3yLwIDAQAB";
	String privateKeyStr = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANPDsCVQngugJhEgfe/6uMGlDRUq1vXoGmz9KN9BYLGb3rrPV3UMazVyoYsO/OPozRq9h0PNedUeU2S7inxUSx2xClzMK3mRbZ+ZaC460AP/owK5ShCg3A+k+KbDD7tsYrS91Yo8qguA59+kbR42dJ1hYOhbAZxWhTpIsy2u3fIvAgMBAAECgYEAiZn5pnWZDOLWeYCMdNiNHz85ngyFO6rDKRjjaxaXVzF6bBb4tFUKgONotuxZRVrrk7md4F/vD52yAJ2gYiN/3q6ThIKPI1YzzV1rP7YLZM/5gU+unD6AIKDSuHVIM3+ffKyE+G73JRzjAGijVoWuMGddH/sMfDvaCGMg2eB+OlkCQQD9bIZ1xtM0kHOb1fAYv1D8HCl0Xho9nPjCQ2D7VnrHyuypsaRKp08d1v43RtS2HVMJIveO9T3SmAzoJmLHm6q9AkEA1erBA6KG4/Wu8BVxa+XePw6J6QMkrPURplzMrzLg7cVjmjFk82n1gIonqTS+a0Qw/B5S8691rPcmHstwP23VWwJBANKmAcImSWq444/WLaO0axGUKxUSH0e1kcSQEy33vUkTMNMA2OpA1e+cxGSYGLlj+KBwk0weJ4xEXP4e4h6/ExUCQAD/sZsEvUB/OyvfzcHFNv5wYPB3lUpBcq2mLUZ8JFS34TktFd2VFxJcksbVejYiAWCL+7MrlI8UMFdgd8u0BZUCQFcLMSozqiLVv2/c5ni1cb8GQE4MJZnUEqwaTOU6ZjW7VGXb7zP65Rh5zCP1mnGg8NaHx5m3L05w8dQV4smql4A=";

	System.out.println("---------------私钥签名过程------------------");
	String content = "{\"body\":{\"bankcardno\":\"6A5BBD489D7D37612CD82EC42DBDC49375C404980BA00BFF\",\"bankcode\":\"ABC\",\"bankname\":\"农业银行\",\"bankno\":\"0103\",\"cdflag\":\"D\",\"cityno\":\"440200\",\"currenttype\":\"156\",\"custtype\":\"1\",\"identityno\":\"6D9C22327B6D9441FDC0568F817E015E4F3D6F993DAA1F98\",\"identitytype\":\"01\",\"mctuserid\":\"1\",\"name\":\"11\",\"phone\":\"13722222222\",\"provinceno\":\"440000\",\"pubpri\":\"PR\"},\"head\":{\"bizcode\":\"2003\",\"merchcode\":\"8002\",\"senddate\":\"20160809\",\"sendtime\":\"154135\",\"seqid\":\"7075d267-5fcb-48ce-a4f5-00a2f682de2d\",\"version\":\"1.0\"}}";
	String signstr = RSASignatureUtil.sign(content, privateKeyStr);
	System.out.println("签名原串：" + content);
	System.out.println("签名串：" + signstr);
	System.out.println();

	System.out.println("---------------公钥校验签名------------------");
	System.out.println("签名原串：" + content);
	System.out.println("签名串：" + signstr);
	// WdeNRH9Huhe3t/qptyB5cOETBrKcY855gfcZp25gXuHSqQw
	// eCTz8kxk9eeQK4iPa9aTtEQpxXn3eTjhekzvo4SColfXVCUJU12ZEv5o8RoHUwSChS7ZM79bppB5BDYHnKNps1uGNisvbKpIiRAl7mza66Dy4Nn29y2kHkwSG0c=
	// WbopeV14if8u8iUhnAHBJbx o4TTi2ggFLhWZM bLwNGhX8
	// dPdpZR0fyc7rSTUgM8H3wAraLuBBSUZDz20vHWsH/8GsSWdIjqkxA3GvSj/0Kt1lrQQQ/xNpeJgdP05hlRJSPMVnlErpglp2XqKjNmBTpA4RfEqEjdl
	// wtERpL0=
	System.out.println("验签结果：" + RSASignatureUtil.verify(content, signstr, publicKeyStr));
	System.out.println();

    }

}